﻿using Enter.Admin.Entities;
using Enter.Admin.Enums;
using Enter.Admin.Utils;
using FluentScheduler;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using System;
using System.Linq;
using System.Collections.Generic;
using System.Threading;

namespace Enter.Admin.Tasks
{
    public class NoticeJob : IJob
    {
        private int executionCount = 0;

        private readonly ILogger _logger;
        private readonly IFreeSql _fsql;
        private readonly IConfiguration _configuration;
        public NoticeJob(ILogger logger, IFreeSql fsql, IConfiguration configuration) 
        {
            _logger = logger;
            _fsql = fsql;
            _configuration = configuration;
        }

        public void Execute()
        {
            try
            {
                // ExecutionOutTime 45  执行查封、冻结财产到期日
                // SealOutTime 保全到期前45日提前  保全到期日/查封、冻结到期日
                // CourtTime   开庭提前10日提醒
                // RenewalTime 委托到期日前45日提醒 委托到期日/续聘到期日
                SearchForNoticeDating(EnumNoticeDatingNoticeType.Archive_ExecutionOutTime, 45);
                SearchForNoticeDating(EnumNoticeDatingNoticeType.Archive_SealOutTime, 45);
                SearchForNoticeDating(EnumNoticeDatingNoticeType.Archive_RenewalTime, 45);
                SearchForNoticeDating(EnumNoticeDatingNoticeType.Archive_CourtTime, 10);

                var count = Interlocked.Increment(ref executionCount);
                _logger.LogInformation("定时任务服务运行. Count: {Count}", count);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "定时任务执行异常.");
            }
        }

        private void SearchForNoticeDating(EnumNoticeDatingNoticeType ntype, int date)
        {
            var currDate = DateTime.Now.Date;
            var needNotices = _fsql.Select<NoticeDating>().Where(t => t.NoticeType == (int)ntype && t.Dating.Date >= currDate && t.Dating.Date <= currDate.AddDays(date) && t.IsNoticed == false && t.IsDeleted == false).ToList();
            foreach (var notice in needNotices)
            {
                SendForArchive(notice);
                _fsql.Update<NoticeDating>().Set(t => new { Noticed = true }).Where(t => t.Id == notice.Id).ExecuteAffrows();
            }
        }

        // ExecutionOutTime 45  执行查封、冻结财产到期日
        // SealOutTime 保全到期前45日提前  保全到期日/查封、冻结到期日
        // CourtTime   开庭提前10日提醒
        // RenewalTime 委托到期日前45日提醒 委托到期日/续聘到期日
        private void SendForArchive(NoticeDating notice)
        {
            try
            {
                Archive archive = _fsql.Select<Archive>().Where(t => t.Id == notice.FromId && t.IsDeleted == false).First();
                var title = string.Empty;
                var body = string.Empty;
                switch (notice.NoticeType) 
                {
                    case (int)EnumNoticeDatingNoticeType.Archive_SealOutTime:
                        title = "保全到期提醒";
                        body = string.Format("合同编号:{0}<br/>保全到期日:{1}", 
                            archive.ContractNo,
                            notice.Dating.ToString(DateFormatConverter.Format_yyyyMMdd)
                            );
                        break;
                    case (int)EnumNoticeDatingNoticeType.Archive_CourtTime:
                        title = "开庭日提醒";
                        body = string.Format("合同编号:{0}<br/>开庭日:{1}", 
                            archive.ContractNo,
                            notice.Dating.ToString(DateFormatConverter.Format_yyyyMMddHHmmss)
                            );
                        break;
                    case (int)EnumNoticeDatingNoticeType.Archive_RenewalTime:
                        title = "委托到期提醒";
                        body = string.Format("合同编号:{0}<br/>委托到期日:{1}",
                            archive.ContractNo,
                            notice.Dating.ToString(DateFormatConverter.Format_yyyyMMdd)
                            );
                        break;
                    case (int)EnumNoticeDatingNoticeType.Archive_ExecutionOutTime:
                        title = "执行查封、冻结财产到期提醒";
                        body = string.Format("合同编号:{0}<br/>执行查封、冻结财产到期日:{1}",
                            archive.ContractNo,
                            notice.Dating.ToString(DateFormatConverter.Format_yyyyMMdd)
                            );
                        break;
                }
                // 发送消息;
                _fsql.Insert<Notice>(new Notice
                {
                    Id = 0,
                    ToUserId = archive.ChargeUserId2,
                    CreateTime = DateTime.Now,
                    Note = body,
                    Title = title,
                    ObjectType = 1,
                    ObjectId = archive.Id,
                    NoticeType = notice.NoticeType,
                    Readed = false,
                    UpdateTime = DateTime.Now,
                }).ExecuteAffrows();
                // 发送邮件;
                var mailModel = _configuration.GetSection("Mail").Get<MailModel>();
                mailModel.Send(title, body);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "发送消息和邮件异常.");
            }
        }
    }
}
